[comment {-*- flibs -*- doctools manpage}]
[manpage_begin keyvars n 1.0]
[copyright {2015 Arjen Markus <arjenmarkus at sourceforge dot net>}]
[moddesc flibs]
[titledesc {Input facility}]

[description]

The [term keyvars] module was inspired by the observations that auxiliary programs that you create
for doing your job, such as converting one type of file into another, because that is more conventient
for the task at hand, often require a small amount of input, say four or five parameters. It is easy
enough to use a few read statements to read them from a file, but that often means fairly little
checking, because it is "just" an auxiliary program, to be used by yourself only and documentation
is more often than not only contained in the source code (or more honestly: the source code is the
documentation).

To solve the problem of documenting the input and checking that all is there, at least partly,
you can use this module:
[list_begin bullet]
[bullet]
You specify which variables are to be read from the input file.
[bullet]
Each input variable is associated with a short meaningful name and a short description.
[bullet]
Reading the data is handled by a single subroutine call, as is the reporting of the values that
were read and providing support.
[bullet]
The input file format is either that of a simple INI file or of an INI file without sections.
A "#" indicates the start of a comment. Here is a simple illustration:
[example {
# Example of an input file for keyvars
# Text after a # is comment
#
int = 2
real = 1.234
char = A string of several words
}]
where space around the equal sign are not significant.
[list_end]

Here is a simple example:

[example {
program demo
    use keyvars

    implicit none

    integer :: x
    real    :: y
    character(len=20) :: string

    x = -1
    y = -1.0

    call get_values( 'keyvars.inp', [keyvar("int",  x, "Integer value"), &
                                     keyvar("real", y, "Real value"), &
                                     keyvar("char", string, "Some text")] )

    write(*,*) 'x = ', x
    write(*,*) 'y = ', y
    write(*,*) 'string = ', string

end program demo
}]

The subroutine [term get_values] first looks at the command-line arguments:
[list_begin bullet]
[bullet]
Arguments [term {-?, /?, -h, -help, --help}] are all recognised as a request for displaying some
help text. It will print the keywords and the description and then stop.
[bullet]
Arguments [term {-i, -input, --input}] must be followed by the name of the input file the user
wants to use. It then reads that particular file instead of the file name that was passed.
[bullet]
Arguments [term {-o, -output, --output}] indicate that the user wants a template of the input.
The argument must be followed by the name of that file. The routine will simply write the
template and stop. The template includes the descriptions as comments.

The array of variables (!) is formed via the [term keyvar] function. Basically, this function
returns a [term keyvar_data] value that contains all there is to know about the variable.
For its proper functioning it stores a pointer to the variable.
[list_end]

[emph Note:] The algorithm was implemented without any consideration of duplicate keys either
in the array or the input file. What happens if a key is not unique therefore depends on the
exact implementation.

[section "ROUTINES"]
There are two public routines:

[list_begin definitions]

[call [cmd "call get_values( filename, args )"]]
This subroutine reads the given input file and stores the values it found in the variables
defined in the array [term args]. More details provided above.

[list_begin arg]
[arg_def character(len=*) filename]
Name of the file to be read, unless overwritten via the [term -input] option.

[arg_def "type(keyvar_data), dimension(:)" args]
Array specifying the variables as well as the associated keywords and descriptive texts. Construct
or fill it using the [term keyvar] function.
[list_end]


[call [cmd "arg = keyvar( keyword, var, description )"]]
This function returns a value of type [term keyvar_data]. It fills the components
of this derived type with a pointer to the variable [term var], so that it can be
set automatically. The variable itself is one of the basic types: integer,
single and double precision real, logical or a character string of any length.

[list_begin arg]
[arg_def character(len=*) keyword]
The keyword by which the variable is to be found in the input.

[arg_def scalar var]
The variable to be assigned a value from the input file.

[arg_def character(len=*) description]
The description of the variable, serves as documentation in the template.
[list_end]


[call [cmd "arg = keyvar( section, keyword, var, description )"]]
Alternative form of the [term keyvar] function. In this case you can specify the section the variable
should come from. Section names appear in the input file as "[lb]section[rb]".

[list_begin arg]
[arg_def character(len=*) section]
The section the keyword belongs to.

[arg_def character(len=*) keyword]
The keyword by which the variable is to be found in the input.

[arg_def scalar var]
The variable to be assigned a value from the input file.

[arg_def character(len=*) description]
The description of the variable, serves as documentation in the template.
[list_end]

[list_end]

[emph Notes:]
[list_begin bullet]
[bullet]
The module uses deferred-length characters and this requires a recent version of the Fortran
compiler. For [term gfortran] you need at least 4.9.

[bullet]
The implementation does not care about duplicate keys, as remarked above. This basically means
that what happens if you use duplicate keys, depends on the details of the implementation and
is therefore not documented here.
[list_end]

[manpage_end]
